# -*- coding: UTF-8 -*-
"""
@Project :xlx-fastapi
@File    :admin_router.py
@Author  :xlx-ali
@Date    :2024/06/24 09:16 星期一
"""
import io
import json
import os
from base64 import b64encode
from typing import Annotated, Any, Dict

from fastapi import APIRouter, Request, Depends, Header, UploadFile, File
from fastapi.params import Query
from slowapi import Limiter
from slowapi.util import get_remote_address

from app import dao
from app import utils
from app.service import adminsvc
from app.types import apiproto, appproto
from app.types.jwtdata import JwtData
from app.utils.aliyun_oss import AliyunOSS
from app.utils.jwt_util import JwtManageUtil
from app.utils.str_util import StringUtil

router = APIRouter(prefix="/base_mange", tags=["后端相关接口"])

limiter = Limiter(key_func=get_remote_address)


def get_current_user(Authorization: Annotated[str | None, Header()] = None) -> apiproto.AdminUserDetailProto:
    jwtUtil = JwtManageUtil()
    token = Authorization.replace("Bearer ", "")
    user: JwtData = jwtUtil.decode(token, JwtData)
    userInfo = dao.redis_dao.get(user.id)
    userInfo = json.loads(userInfo)
    return apiproto.AdminUserDetailProto(**userInfo)


@router.get("/login/captcha")
async def get_captcha(request: Request) -> utils.HttpResponse:
    session = request.session
    captcha_text = StringUtil.generate_captcha_text()
    session["code"] = captcha_text
    captcha_image = StringUtil.generate_captcha_image(captcha_text)
    captcha_stream = io.BytesIO(captcha_image)
    captcha_bytes = captcha_stream.getvalue()
    base64_encoded_captcha = b64encode(captcha_bytes).decode('utf-8')
    res = {'src': 'data:image/png;base64,' + base64_encoded_captcha}
    return utils.ResponseSuccess(res)
    # captcha_stream.seek(0)  # 确保文件指针在文件开始位置
    # return StreamingResponse(captcha_stream, media_type="image/png")


@router.post("/upload/file")
async def upload_pic(file: UploadFile = File(...)) -> utils.HttpResponse:
    filename = file.filename
    content = await file.read()
    base_name, suffix = os.path.splitext(filename)
    oss = AliyunOSS()
    key = StringUtil.get_uniqid("hex") + suffix
    result = oss.upload_file(key, content)
    url = ""
    if result:
        url = "https://ln-zhijian.oss-cn-beijing.aliyuncs.com/" + key
    res = {'filename': base_name, 'src': url}
    return utils.ResponseSuccess(res)


@router.post("/uploadFile")
async def upload_files(file: UploadFile = File(...)) -> utils.HttpResponse:
    filename = file.filename
    content = await file.read()
    base_name, suffix = os.path.splitext(filename)
    oss = AliyunOSS()
    key = StringUtil.get_uniqid("hex") + suffix
    result = oss.upload_file(key, content)
    print('uploadFile', result)
    url = ""
    if result:
        url = "https://ln-zhijian.oss-cn-beijing.aliyuncs.com/" + key
    res = {'filename': base_name, 'src': url}

    return utils.ResponseSuccess(res)


@router.post("/admin/login")
@limiter.limit("5/minute")
async def adminLogin(param: apiproto.AdminUserLoginRequest, request: Request) -> utils.HttpResponse:
    """
    后端登录
    """
    session = request.session
    stored_captcha = session.get("code")
    print('验证码', stored_captcha, param.code)
    if param.code.upper() != stored_captcha:
        return utils.ResponseFail("验证码错误", code=0)
    print("后端登录", stored_captcha, param)
    result = adminsvc.AadminUserService.login(param, request)
    return result


@router.get("/admin/logout")
async def adminLogout(UserInfo: apiproto.AdminUserDetailProto = Depends(get_current_user)) -> utils.HttpResponse:
    dao.AdminIdentityTokenOperateDao.delByAdminId(UserInfo.id)
    return utils.ResponseSuccess('退出成功')


@router.get("/admin/userinfo")
async def userinfo(UserInfo: apiproto.AdminUserDetailProto = Depends(get_current_user)) -> utils.HttpResponse:
    admin_info = dao.AdminQueryDao.findByUserName(UserInfo.username)
    if admin_info is None:
        return utils.ResponseFail('没有找到用户信息', 50001)
    if admin_info.status != 1:
        return utils.ResponseFail('当前管理员账号已被锁定，请联系超级管理员', 50003)
    roleinfo = dao.AdminRoleQueryDao.findByid(admin_info.role_id)
    UserInfo = {"id": admin_info.id, "username": admin_info.username, "password": admin_info.password,
                "pwd_hash": admin_info.pwd_hash, "role_id": admin_info.role_id,
                "addtime": utils.StringUtil.format_timestamp_to_str(admin_info.addtime),
                "last_login_time": utils.StringUtil.format_timestamp_to_str(admin_info.last_login_time),
                "last_login_ip": admin_info.last_login_ip,
                "last_login_ipaddress": admin_info.last_login_ipaddress, "openid": admin_info.openid,
                "is_sc": admin_info.is_sc, "mobile": admin_info.mobile, "avatar": admin_info.avatar,
                "status": admin_info.status, "customer_exceed": admin_info.customer_exceed,
                'access': roleinfo.access if roleinfo.access == 'all' else json.loads(roleinfo.access),
                'access_mobile': roleinfo.access_mobile if roleinfo.access_mobile == 'all' else json.loads(
                    roleinfo.access_mobile),
                'access_export': 1 if roleinfo.access == 'all' else roleinfo.access_export,
                'access_delete': 1 if roleinfo.access == 'all' else roleinfo.access_delete,
                'access_set_service': 1 if roleinfo.access == 'all' else roleinfo.access_set_service,
                'rolename': roleinfo.name}

    return utils.ResponseSuccess(UserInfo)


@router.post("/config/save")
async def set_config() -> utils.HttpResponse:
    result = StringUtil.webConfigGetCache()
    return utils.ResponseSuccess(result)


@router.get("/login/config")
async def login_config() -> utils.HttpResponse:
    result = StringUtil.webConfigGetCache()
    return utils.ResponseSuccess(result)


@router.get("/member/loginlog")
async def login_log(uid: int = 0, page: int = 1, pagesize: int = 10, request: Request = None) -> utils.HttpResponse:
    result = adminsvc.MemberService.get_login_log(uid, page, pagesize, request)
    return utils.ResponseSuccess(result)


@router.get("/member/actionlog")
async def action_log(utype: int = 0, uid: int = 0, keyword: str = '', page: int = 1, pagesize: int = 10,
                     request: Request = None) -> utils.HttpResponse:
    result = adminsvc.MemberService.get_action_log(utype, uid, keyword, page, pagesize, request)
    return utils.ResponseSuccess(result)


@router.get("/classify/index")
async def classify_index(type_str: str = Query(..., description="Type parameter", alias="type"),
                         request: Request = None) -> utils.HttpResponse:
    if not type_str:
        return utils.ResponseFail('type不能为空', 10001)
    params: Dict[str, Any] = {}
    for key, value in request.query_params.items():
        if key.lower() != 'type':  # 确保 'type' 不被包含在内
            params[key] = value
    result = adminsvc.ClassifyService.index(type_str, **params)
    return result


@router.get("/member/index")
async def member_index(list_type: str = None, key_type: int = 0, keyword: str = None, status: str = None,
                       sort: str = None, regtime: str = None, platform: str = None, utype: int = 0, is_openid: int = 0,
                       is_email: int = 0, page: int = 1, pagesize: int = 10,
                       request: Request = None) -> utils.HttpResponse:
    return adminsvc.MemberService.index(list_type, key_type, keyword, status, sort, regtime, platform, utype, is_openid,
                                        is_email, page, pagesize, request)


@router.get("/article/category/list")
async def article_category_list(page: int = 1, pagesize: int = 10, request: Request = None) -> utils.HttpResponse:
    return adminsvc.ArticleService.category_list(page=page, pagesize=pagesize)


@router.post("/article/category/updata")
async def article_category_updata(data: appproto.ArticleCategoryInput, request: Request = None) -> utils.HttpResponse:
    if not data.id:
        return utils.ResponseFail('更新失败', 10000)
    return adminsvc.ArticleService.category_updata(data)


@router.post("/article/category/add")
async def article_category_add(data: appproto.ArticleCategoryInput, request: Request = None) -> utils.HttpResponse:
    return adminsvc.ArticleService.categoy_add(data)


@router.post("/article/category/del")
async def article_category_del(data: appproto.DelRequest, request: Request = None) -> utils.HttpResponse:
    return adminsvc.ArticleService.categoy_del(data.ids)


# @router.get("/admin/init")
# async def admininit() -> utils.HttpResponse:
#     result = adminsvc.AadminUserService.adminInit()
#     return utils.ResponseSuccess(result)

@router.get("/article/list")
async def article_list(cid: int = 0, is_display: int = 0, key_type: str = '', keyword: str = '', page: int = 1,
                       pagesize: int = 10, request: Request = None) -> utils.HttpResponse:
    return adminsvc.ArticleService.get_article_list(cid=cid, is_display=is_display, key_type=key_type, keyword=keyword,
                                                    page=page, pagesize=pagesize)


@router.post("/article/updata")
async def article_updata(data: appproto.ArticleInputData) -> utils.HttpResponse:
    return adminsvc.ArticleService.article_updata(data)


@router.post("/article/add")
async def article_add(data: appproto.ArticleInputData) -> utils.HttpResponse:
    result = adminsvc.ArticleService.article_add(data)
    return utils.ResponseSuccess(result)


@router.post("/article/del")
async def article_del(data: appproto.DelRequest, request: Request = None) -> utils.HttpResponse:
    return adminsvc.ArticleService.article_del(data.ids)


@router.get("/guestbook/list")
async def guestbook_list(uid: int = 0, is_lock: int = 2, key_type: str = '', keyword: str = '',
                         page: int = 1,
                         pagesize: int = 10, request: Request = None) -> utils.HttpResponse:
    return adminsvc.GuestBookService.get_guestbook_list(uid, is_lock, key_type, keyword, page, pagesize)


@router.get("/guestbook/reply")
async def guestbook_reply(parent_id: int, page: int = 1,
                          pagesize: int = 10, request: Request = None) -> utils.HttpResponse:
    return adminsvc.GuestBookService.get_guestbook_reply(parent_id, page, pagesize)


@router.post("/guestbook/add")
async def guestbook_add(data: appproto.GuestBookRequestData) -> utils.HttpResponse:
    return adminsvc.GuestBookService.add(data)


@router.post("/guestbook/update")
async def guestbook_update(data: appproto.GuestBookRequestData) -> utils.HttpResponse:
    return adminsvc.GuestBookService.update(data)


@router.post("/guestbook/del")
async def guestbook_del(data: appproto.DelRequest, request: Request = None) -> utils.HttpResponse:
    return adminsvc.GuestBookService.guestbook_del(data.ids)


@router.get("/complaint/list")
async def guestbook_list(uid: int = 0, status: str = '', key_type: str = '', keyword: str = '',
                         page: int = 1,
                         pagesize: int = 10, request: Request = None) -> utils.HttpResponse:
    return adminsvc.ComplaintService.get_complaint_list(uid, status, key_type, keyword, page, pagesize)


@router.post("/complaint/add")
async def complaint_add(data: appproto.ComplaintData) -> utils.HttpResponse:
    return adminsvc.ComplaintService.add(data)


@router.post("/complaint/update")
async def complaint_update(data: appproto.ComplaintData) -> utils.HttpResponse:
    return adminsvc.ComplaintService.update(data)


@router.post("/complaint/del")
async def complaint_del(data: appproto.DelRequest, request: Request = None) -> utils.HttpResponse:
    return adminsvc.ComplaintService.guestbook_del(data.ids)


@router.get("/train/list")
async def train_list(key_type: str = '', keyword: str = '', page: int = 1,
                     pagesize: int = 10) -> utils.HttpResponse:
    return adminsvc.TrainService.get_train_list(key_type, keyword, page, pagesize)


@router.post("/train/add")
async def train_add(data: appproto.TrainInputData) -> utils.HttpResponse:
    return adminsvc.TrainService.add(data)
